package com.ofd.sign.config;


import cn.hutool.core.codec.Base64;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import com.ofd.sign.utils.AssertUtil;
import com.ofd.sign.utils.CoreUtil;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import static com.ofd.sign.constant.CoreConstants.*;

/**
 * 鉴权
 *
 * @author wangrenjie
 */
@Slf4j
public class AuthInterceptor extends HandlerInterceptorAdapter {


    @Value("${system.secretKey}")
    private String secretKey;

    @Value("${system.timeout}")
    private int timeout;

    @Value("${system.template}")
    private String template;

    @Value("${system.id}")
    private String currentSysId;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        val token = request.getHeader(SIGN_AUTHORIZATION);
        AssertUtil.authCheck(StrUtil.isBlank(token), "请求失败,Header中不存在[Sign-Authorization]");
        val timeStr = request.getHeader(SIGN_TIME);
        AssertUtil.authCheck(StrUtil.isBlank(token), "请求失败,Header中不存在[Sign-Time]时间戳");
        AssertUtil.authCheck(timeStr.length() != 13, "请求失败,[Sign-Time]时间戳格式不正确");
        Long time = Long.valueOf(timeStr);
        //默认配置 30秒超时
        val spendMs = DateUtil.spendMs(time) / 1000;
        AssertUtil.authCheck(spendMs > timeout, "请求失败,已超时");
        val sysId = request.getHeader(SYS_ID);
        AssertUtil.authCheck(StrUtil.isBlank(sysId) || !currentSysId.equals(sysId), "请求失败,错误的请求平台");
        val source = StrUtil.format(template, Base64.decode(secretKey), timeStr, sysId);
        log.info("签名原文:{}", source);
        val digestHex = MD5.create().digestHex(source);
        AssertUtil.authCheck(!digestHex.equalsIgnoreCase(token), "请求失败,无效的[Sign-Authorization]");
        CoreUtil.setSysId(sysId);
        return true;
    }


    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        CoreUtil.cleanSysId();
    }

    /**
     * 测试Token生成
     *
     * @param args
     */
    public static void main(String[] args) {
        val millis = System.currentTimeMillis();
        System.out.println("时间戳:" + millis);
        val source = StrUtil.format("{}-{}-{}", "mG2t4KTOUJ1dwCABZ8hF3jW", millis, "C000000");
        System.out.println("签名原文:" + source);
        val sign = MD5.create().digestHex(source);
        System.out.println("签名值:" + sign);
    }

}